package net.homelinux.chaoswg.io.renga.krypto.gui.operations.reader;

import java.util.List;

import net.homelinux.chaoswg.io.higherorderfunctions.AbstractUnaryFunction;
import net.homelinux.chaoswg.io.higherorderfunctions.UnaryFunction;
import net.homelinux.chaoswg.io.renga.core.gui.operations.Control;
import net.homelinux.chaoswg.io.renga.core.gui.operations.Operation;
import net.homelinux.chaoswg.io.renga.core.gui.operations.reader.CommonOperationReader;
import net.homelinux.chaoswg.io.renga.core.gui.operations.reader.OperationReader;
import net.homelinux.chaoswg.io.renga.core.registries.ReaderRegistry;
import net.homelinux.chaoswg.io.renga.krypto.gui.operations.LoopOperation;

import org.jdom.Element;

public class LoopOperationReader extends AbstractUnaryFunction<Operation, Element> implements UnaryFunction<Operation, Element>, OperationReader {

    @SuppressWarnings("unchecked")
    public Operation apply(final Element arg0) throws IllegalArgumentException {
        final LoopOperation lo = new LoopOperation ();
        
        final Element nameElement = arg0.getChild("name");
        if (nameElement != null) {
            lo.setName(nameElement.getText());
        }
        
        final List<Element> operationChildren = arg0.getChildren("operation");
        
        final ReaderRegistry orr = ReaderRegistry.getOperationRegistry();
        
        final Control control = new Control ();
        
        for (final Element e : operationChildren) {
            Class<? extends Operation> clazz = null;
            try {
                clazz = ((Class<? extends Operation>)Class.forName(e.getAttributeValue("type")));
            } catch (Exception excp) {
                excp.printStackTrace();
            }
            if (clazz != null) {
                final OperationReader or = ((OperationReader)orr.getOperationReader( clazz ));
                
                final Operation o = or.apply(e);
                
                if (o != null) {
                    control.addOperation(o, true);
                }
            }
        }
        
        lo.setControl(control);
        control.addObserver(lo);
        
        lo.setInputs(Integer.parseInt (arg0.getChildText("inputs")));
        lo.setOutputs(Integer.parseInt(arg0.getChildText("outputs")));

        final CommonOperationReader cor = new CommonOperationReader ();
        cor.apply(lo, arg0);
        
        return lo;
    }
}
